import { cloneDeep } from 'lodash-es'
/**
 * 元素是否在视窗中
 * @param param0 selectors:dom列表
 * @returns
 */
export default function useViewObServer({
  selectors,
  config,
  onEnter,
  onLeave,
  whoIsActive = 'first',
}: {
  selectors: (string | Ref<Element>)[] | Ref<Element[]> // (选择器|ref)数组  | ref<dom[]>
  config?: IntersectionObserverInit
  onEnter?: (n: number[]) => void
  onLeave?: (n: number[]) => void
  whoIsActive?: 'first' | 'last'
}) {
  const isSupport = ref<boolean>(true)
  const inViewSet = ref<Set<number>>(new Set())
  const io = new IntersectionObserver(
    (entries) => {
      const enter: number[] = []
      const leave: number[] = []
      entries.forEach((entry) => {
        const TheIndex = Number(entry.target.getAttribute('USE_VIEW_OBSERVER_INDEX'))
        if (entry.isIntersecting) {
          // 进入视区
          enter.push(TheIndex)
          inViewSet.value.add(TheIndex)
        } else {
          // 退出视区
          leave.push(TheIndex)
          inViewSet.value.delete(TheIndex)
        }
      })
      if (onEnter && enter?.length) onEnter(enter)
      if (onLeave && leave?.length) onLeave(leave)
    },
    Object.assign({ root: null, rootMargin: '0px 50% 0px 50%', threshold: 0 }, config),
  )

  onMounted(() => {
    if (!IntersectionObserver) return (isSupport.value = false)
    const doms = isRef(selectors)
      ? selectors.value
      : selectors.map((selector) => {
          if (isRef(selector)) {
            return selector.value
          } else {
            return document.querySelector(selector) as Element
          }
        })

    doms
      .filter((e) => e)
      .map((dom, i) => {
        dom.setAttribute('USE_VIEW_OBSERVER_INDEX', i + '')
        io.observe(dom)
      })
  })

  const inView = computed(() => [...inViewSet.value])
  const activeIndex = computed(() => {
    const list = cloneDeep(inView.value).sort((a: number, b: number) => a - b)
    switch (whoIsActive) {
      case 'first':
        return list.shift()
      case 'last':
        return list.pop()
    }
  })

  onBeforeUnmount(() => {
    io.disconnect()
  })
  return {
    isSupport,
    inView,
    activeIndex,
  }
}
